package com.wangyb.wework.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.ServiceException;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.config.properties.TokenProperties;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysUserService;
import com.wangyb.wework.entity.agent.WwAgent;
import com.wangyb.wework.entity.employee.WwEmployee;
import com.wangyb.wework.exception.CommonException;
import com.wangyb.wework.service.IWwEmployeeService;
import com.wangyb.wework.service.agent.IWwAgentService;
import com.wangyb.wework.service.contact.IWwContactService;
import com.wangyb.wework.utils.crypt.RSAUtils;
import com.wangyb.wework.utils.WxApiUtils;
import com.wangyb.wework.utils.WxTokenUtils;
import com.wangyb.wework.vo.WwContactVo;
import io.swagger.annotations.Api;
import lombok.RequiredArgsConstructor;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.spring5.SpringTemplateEngine;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.util.HashMap;

/**
 * @Author: wangyb
 * @Date: 2021/7/22 10:44 上午
 */
@Api(value = "侧边栏控制器", tags = {"侧边栏控制器"})
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@RestController
public class SidebarController {
	@Autowired
	private IWwAgentService iWwAgentService;
	@Autowired
	private SidebarProperties sidebarProperties;
	@Autowired
	private IWwEmployeeService iWwEmployeeService;
	@Autowired
	private ISysUserService iSysUserService;
	@Autowired
	private SysLoginService sysLoginService;
	@Autowired
	private TokenService tokenService;
	@Autowired
	private UserDetailsService userDetailsService;
	@Autowired
	private TokenProperties tokenProperties;
	@Autowired
	private IWwContactService iWwContactService;
	@Autowired
	private SpringTemplateEngine templateEngine;

	@GetMapping("/wxJsSdk/config")
	public AjaxResult wxJSConfig(
		@NotNull(message = "企业 ID 无效") Long corpId,
		@RequestParam(defaultValue = "") String uriPath,
		@RequestParam(defaultValue = "0") Long agentId
	) {
		//TODO corpId从参数获取，这里默认先填这个
		corpId = 1L;
		String ticket = "";
		WwAgent agent = null;
		if (agentId > 0) {
			agent = iWwAgentService.getBaseMapper().selectById(agentId);
			// 应用 ticket
			ticket = WxTokenUtils.getJsapiTicketOfAgent(corpId, agent);
		} else {
			// 企业 ticket
			ticket = WxTokenUtils.getJsapiTicketOfCorp(corpId);
			agent = iWwAgentService.getDefaultAgent(corpId);
		}
		if (agent == null){
			throw new CommonException("当前应用没有找到，请检查");
		}

		String noncestr = "" + System.currentTimeMillis();
		String timestamp = "" + System.currentTimeMillis();

		String str1 = "jsapi_ticket=" + ticket +
			"&noncestr=" + noncestr +
			"&timestamp=" + timestamp +
			"&url=" + sidebarProperties.getWebUrl() + uriPath;
		String sign = DigestUtils.sha1Hex(str1);

		String wxCorpId = WxTokenUtils.getCorpEntity(corpId).getWxCorpId();


		String wxAgentId = agent.getWxAgentId();

		HashMap<String, String> map = new HashMap<>(6);
		map.put("appId", wxCorpId);
		map.put("corpid", wxCorpId);
		map.put("agentid", wxAgentId);
		map.put("nonceStr", noncestr);
		map.put("timestamp", timestamp);
		map.put("signature", sign);
		map.put("sidebarAppName",agent.getSidebarAppName());
		return AjaxResult.success(map);
	}
	/**
	 * @param agentId      应用 ID
	 * @param isJsRedirect 是否跳转回本页面 0, 否; 1, 是
	 * @param act          跳转回本页面时带的自定义参数，如客户标识，素材库标识
	 */
	@GetMapping("/agent/oauth")
	public AjaxResult oauth(
		@NotNull(message = "应用 ID 不能为空") Integer agentId,
		@RequestParam(defaultValue = "0") String isJsRedirect,
		@RequestParam(defaultValue = "") String act
	) {
		// 获取企业微信 id
		WwAgent agent = iWwAgentService.getBaseMapper().selectById(agentId);
		Long corpId = agent.getCorpId();
		if (null == corpId || corpId < 1) {
			throw new CommonException("应用 id 未关联企业");
		}

		String wxCorpId = WxTokenUtils.getCorpEntity(corpId).getWxCorpId();
		if (null == wxCorpId) {
			throw new ServiceException("企业微信 id 获取失败, 未查到对应企业");
		}

		String redirectUrl = sidebarProperties.getApiUrl() + "/agent/oauth/callback"
			+ "?agentId=" + agentId
			+ "&isJsRedirect=" + isJsRedirect
			+ "&act=" + act;

		String url = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
			"appid=" + wxCorpId +
			"&redirect_uri=" + redirectUrl +
			"&response_type=code" +
			"&scope=snsapi_base" +
			"&state=" +
			"#wechat_redirect";

		HashMap<String, String> map = new HashMap<>(1);
		map.put("url", url);
		return AjaxResult.success(map);
	}
	/**
	 * @param agentId      应用 ID
	 * @param isJsRedirect 是否跳转回本页面 0, 否; 1, 是
	 * @param act          跳转回本页面时带的自定义参数，如客户标识，素材库标识
	 * @param code         企业微信回调时返回值
	 */
	@GetMapping("/agent/oauth/callback")
	public void oauth(
		@NotNull(message = "应用 ID 不能为空") Long agentId,
		@RequestParam(defaultValue = "0") String isJsRedirect,
		@RequestParam(defaultValue = "") String act,
		@RequestParam(defaultValue = "") String code,
		HttpServletResponse response
	) throws IOException {

		// 获取企业微信 id
		WwAgent agent = iWwAgentService.getBaseMapper().selectById(agentId);
		Long corpId = agent.getCorpId();
		if (null == corpId || corpId < 1) {
			throw new CommonException("应用 id 未关联企业");
		}

		// 根据 code 查询员工信息
		String wxUserId = WxApiUtils.requestWxUserIdApi(corpId, agent, code);
		WwEmployee employee = iWwEmployeeService.getByWxUserid(wxUserId);

		// 根据员工信息登录
		SysUser user = iSysUserService.getById(employee.getLogUserId());
		if (user == null) {
			throw new CommonException(100013, "登录失败,用户不存在");
		}
		//TODO 记录登录状态
//		String token = JwtUtil.createJWT(36000000, user);
//		RedisUtil.set("mc:user.token" + token, "1");
//		AccountService.updateCorpIdAndEmployeeId(employee.getLogUserId(), employee.getCorpId(), employee.getId());

		AsyncManager.me().execute(AsyncFactory.recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
		LoginUser loginUser = (LoginUser)userDetailsService.loadUserByUsername(user.getUserName());
//		LoginUser loginUser = (LoginUser) authentication.getPrincipal();
		sysLoginService.recordLoginInfo(user);
		// 生成token
		String token = tokenService.createToken(loginUser);



		JSONObject jsonObject = new JSONObject();
		jsonObject.put("corpId", corpId);
		jsonObject.put("token", token);
		jsonObject.put("expire", tokenProperties.getExpireTime() * 60); //application.yml 中配置的为分钟，这里处理成秒
		jsonObject.put("agentId", agentId);
		jsonObject.put("isJsRedirect", isJsRedirect);
		jsonObject.put("act", act);
		jsonObject.put("sidebarAppName",agent.getSidebarAppName());
		AjaxResult<JSONObject> result = AjaxResult.success("登录成功", jsonObject);
		String dataJson = JSON.toJSONString(result);
		String data = RSAUtils.base64EncodeToString(dataJson.getBytes());
		// 微信回调, 需要重定向到前端页面
		String redirectUrl = sidebarProperties.getWebUrl() + "/codeAuth?callValues=" + data;
		response.sendRedirect(redirectUrl);
	}
	@GetMapping("/user/loginShow")
	public AjaxResult getUserInfo(){
		LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
		SysUser user = loginUser.getUser();
		WwEmployee employee = iWwEmployeeService.getByUserId(user.getUserId());
		return AjaxResult.success(employee);
	}
	/**
	 * @description 客户详情接口
	 */
	@GetMapping("/workContact/detail")
	public AjaxResult<WwContactVo> contactDetail(@NotBlank(message = "客户微信 id 不能为空") String wxExternalUserid) {
		WwContactVo contactVo = iWwContactService.getContactVoByWxUserid(wxExternalUserid);
		return AjaxResult.success(contactVo);
	}
}
